﻿using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using Kang.DbDoc.Views;
using Kang.ExtendMethod.Log;
using MahApps.Metro.Controls.Dialogs;
using MahApps.Metro.Controls;
using Chloe.SQLite;
using Chloe.Infrastructure.Interception;
using Kang.DbDoc.DatabaseHelper;
using Microsoft.Data.Sqlite;
using MahApps.Metro.SimpleChildWindow;
using ICSharpCode.AvalonEdit.Highlighting.Xshd;
using ICSharpCode.AvalonEdit.Highlighting;
using System.Reflection;
using Newtonsoft.Json;
using Kang.DbDoc.Models;
using Kang.ExtendMethod;
using System.Text;

namespace Kang.DbDoc
{
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
        readonly Logger logger = LogManager.GetCurrentClassLogger();
        private static string SQLiteConnectionString = "";
        public static string AppDataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "KangDbDoc");
        public static string ConfigPath = Path.Combine(AppDataDir, "config.json");
        public static ConfigJsonModel Config = null;

        public static SQLiteContext sqlite
        {
            get
            {
                return SQLiteConnectionString == "" ? null : new SQLiteContext(new SQLiteConnectionFactory(SQLiteConnectionString));
            }
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            try
            {
                if (Directory.Exists(AppDataDir) != true)
                {
                    Directory.CreateDirectory(AppDataDir);
                }

                using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + ".sql.xshd"))
                {
                    using (var reader = new System.Xml.XmlTextReader(stream))
                    {
                        var sqlDefinition = HighlightingLoader.Load(reader, HighlightingManager.Instance);
                        HighlightingManager.Instance.RegisterHighlighting("SQL", new string[] { ".sql" }, sqlDefinition);
                    }
                }
                using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + ".config.json"))
                {
                    if (!ConfigPath.AsFilePathAndExists())
                    {
                        var json = stream.AsString(Encoding.UTF8);
                        Config = JsonConvert.DeserializeObject<ConfigJsonModel>(json);
                        if (!ConfigPath.AsFilePathAndExists())
                        {
                            File.WriteAllText(ConfigPath, JsonConvert.SerializeObject(Config));
                        }
                    }
                    else
                    {
                        Config = JsonConvert.DeserializeObject<ConfigJsonModel>(File.ReadAllText(ConfigPath));
                        if (Config != null)
                        {
                        }
                    }
                }

                SqliteConnectionStringBuilder builder = new SqliteConnectionStringBuilder();
                builder.DataSource = Path.Combine(AppDataDir, "data.db");
                builder.Password = "Hzkdb4598932!";
                builder.Mode = SqliteOpenMode.ReadWriteCreate;
                SQLiteConnectionString = builder.ToString();

                // SQL监控
                IDbCommandInterceptor interceptor = new DbCommandInterceptor();
                DbInterception.Add(interceptor);

                // 检查SQLite数据表
                using (var sqlite = App.sqlite)
                {
                    sqlite.Session.ExecuteNonQuery(@"
                            CREATE TABLE IF NOT EXISTS kang_db_server
                            (
                              id INTEGER PRIMARY KEY AUTOINCREMENT,
                              name TEXT,
                              database_host TEXT,
                              database_port INTEGER,
                              database_name TEXT,
                              database_username TEXT,
                              database_password TEXT,
                              time_out INTEGER,
                              is_ssl_mode INTEGER,
                              connection_string TEXT,
                              db_type INTEGER,
                              remark TEXT,
                              is_delete INTEGER,
                              update_time TEXT,
                              cteate_time TEXT
                            );");
                }
                logger.Trace($"配置载入完毕！");
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }

            MainWindow mw = new MainWindow();
            mw.Show();
            Current.MainWindow = mw;
        }

        protected override void OnExit(ExitEventArgs e)
        {
            base.OnExit(e);
            using (var stream = new FileStream(ConfigPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
            {
                var data = JsonConvert.SerializeObject(Config).GetBytes();
                stream.Write(data, 0, data.Length);
                stream.Flush();
            }
        }

        public static MessageDialogResult? ShowMessageAsync(string title, string message, MessageDialogStyle style = MessageDialogStyle.Affirmative, MetroDialogSettings settings = null)
        {
            return Current.Dispatcher.Invoke<MessageDialogResult?>(()=>
            {
                MetroWindow mw = Current.MainWindow as MetroWindow;
                if (mw == null)
                {
                    return null;
                }
                if (settings == null)
                {
                    settings = new MetroDialogSettings()
                    {
                        AffirmativeButtonText = "确认",
                        NegativeButtonText = "取消",
                        DefaultButtonFocus = MessageDialogResult.Affirmative
                    };
                }
                return mw.ShowModalMessageExternal(title, message, style, settings);
            });
        }

        public static async Task<T> ShowChildWindowAsync<T>(ChildWindow page)
        {
            MetroWindow mw = Current.MainWindow as MetroWindow;
            if (mw == null)
            {
                return default;
            }
            return await mw.ShowChildWindowAsync<T>(page);
        }
    }
}
